﻿/*
 *  PassBag is multi-platform software that securely manage/store passwords
 *  Copyright (C) <2009>  <Hugo Rodrigues PEREIRA>
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *	
 *  You can find a copy of the GPLv3 at project <root directory>/gpl.txt
 *
 */

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using PassBag.Logic;
using PassBag.Data;
using PassBag.Presentation.Logic;
using PassBag.Utils;

namespace PassBag.Presentation {
    public partial class SynchronizeFilesDialog : Form {

        #region sych list's
        private List<PasswordObject> activePasswordObjectList = null;
        private List<PasswordObject> comparePasswordObjectList = null;

        private List<PasswordObject> onlyInActivePasswordList = null;
        private List<PasswordObject> onlyInComparePasswordList = null; 
        #endregion

        #region properties and properties holder
        private string _activeFile = string.Empty;
        private string _comparedFile = string.Empty;
        private string _activeFilePassword = string.Empty;
        private string _comparedFilePassword = string.Empty;

        public string ActiveFilePassword {
            get {
                return _activeFilePassword;
            }
            set {
                _activeFilePassword = value;
            }
        }

        public string ComparedFilePassword {
            get {
                return _comparedFilePassword;
            }
            set {
                _comparedFilePassword = value;
            }
        }

        public string ActiveFile {
            get {
                return _activeFile;
            }
            set {
                _activeFile = value;
                activeFileName.Text = GetFileName (_activeFile);
            }
        }

        public string ComparedFile {
            get {
                return _comparedFile;
            }
            set {
                _comparedFile = value;
                compFileName.Text = GetFileName (_comparedFile);
            }
        } 
        #endregion

        public SynchronizeFilesDialog () {
            InitializeComponent ();
            this.DialogResult = DialogResult.Cancel;

            LoadRessource ();
        }

        #region Load Resource

        /// <summary>
        /// Loads the ressource.
        /// </summary>
        private void LoadRessource () {
            this.Text = Properties.Resources.SynchronizeFilesDialog_Text;
            this.infoLabel.Text = Properties.Resources.SynchronizeFilesDialog_Title;
            this.label1.Text = Properties.Resources.SynchronizeFilesDialog_ActiveCol;
            this.label2.Text = Properties.Resources.SynchronizeFilesDialog_CompareCol;

            this.label14.Text = Properties.Resources.SynchronizeFilesDialog_LineFileName;
            this.label4.Text = Properties.Resources.SynchronizeFilesDialog_LineNbItems;
            this.label3.Text = Properties.Resources.SynchronizeFilesDialog_LineNbDiff;
            this.label6.Text = Properties.Resources.SynchronizeFilesDialog_LineNbAfterSynch;

            this.groupBox1.Text = Properties.Resources.SynchronizeFilesDialog_GrpSyncOptions;
            this.synchAllRadioButton.Text = Properties.Resources.SynchronizeFilesDialog_SynchTwoCheck;
            this.synchOnlyActiveRadioButton.Text = Properties.Resources.SynchronizeFilesDialog_ActiveOnlyCheck;
            this.synchOnlyComparedRadioButton.Text = Properties.Resources.SynchronizeFilesDialog_ComparedOnlyCheck;

            this.okBtn.Text = Properties.Resources.SynchronizeFilesDialog_SynchBtn;
            this.cancelBtn.Text = Properties.Resources.Global_CancelButton;


        }

        #endregion


        private void CompareFiles () {
            // read list's from file
            activePasswordObjectList = ReadSortedXmlFile (_activeFile, _activeFilePassword);
            comparePasswordObjectList = ReadSortedXmlFile (_comparedFile, _comparedFilePassword);

            if (activePasswordObjectList != null && comparePasswordObjectList != null) {
                onlyInActivePasswordList = new List<PasswordObject> ();
                onlyInComparePasswordList = new List<PasswordObject> ();

                PasswordObjectComparer comp = new PasswordObjectComparer ();
                comp.ComparisonMethod = PasswordObjectComparer.ComparisonType.Id;

                ListSynchronizer.SynchronizeSortedList (activePasswordObjectList, comparePasswordObjectList, comp,
                                                        onlyInActivePasswordList, onlyInComparePasswordList);

                // show compare information
                activeFileNbItems.Text = activePasswordObjectList.Count.ToString ();
                compFileNbItems.Text = comparePasswordObjectList.Count.ToString ();

                activeFileNbDiff.Text = onlyInComparePasswordList.Count.ToString ();
                compFileNbDiff.Text = onlyInActivePasswordList.Count.ToString ();

                nbItemsAfterSynch.Text = Convert.ToString (activePasswordObjectList.Count + onlyInComparePasswordList.Count);
            }
            else {
                MessageDialog.ShowError (this, Properties.Resources.Global_CantBeNull);
            }
        }

        private void SynchronizeFiles () {
            // choose synch mode
            if (synchAllRadioButton.Checked) {
                activePasswordObjectList.AddRange (onlyInComparePasswordList);
                comparePasswordObjectList.AddRange (onlyInActivePasswordList);

                // save the file's
                SavePasswordListToXMLFile (activePasswordObjectList, _activeFile, _activeFilePassword);
                SavePasswordListToXMLFile (comparePasswordObjectList, _comparedFile, _comparedFilePassword);

                // active file updated
                this.DialogResult = DialogResult.OK;
            }
            else if (synchOnlyActiveRadioButton.Checked) {
                activePasswordObjectList.AddRange (onlyInComparePasswordList);

                // save the file
                SavePasswordListToXMLFile (activePasswordObjectList, _activeFile, _activeFilePassword);

                // active file updated
                this.DialogResult = DialogResult.OK;
            }
            else if (synchOnlyComparedRadioButton.Checked) {
                comparePasswordObjectList.AddRange (onlyInActivePasswordList);

                // save the file
                SavePasswordListToXMLFile (comparePasswordObjectList, _comparedFile, _comparedFilePassword);

                // active file not updated
                this.DialogResult = DialogResult.Ignore;
            }
            else {
                MessageDialog.ShowError (this, Properties.Resources.Global_MsgInterfaceError);
            }
        }

        private string GetFileName (string fullName) {
            FileInfo fileInfo = new FileInfo (fullName);

            return fileInfo.Name;
        }

        private List<PasswordObject> ReadSortedXmlFile (string fileName, string password) {
            try {
                List<PasswordCryptObject> passwordCryptList = new List<PasswordCryptObject> ();
                List<PasswordObject> passwordList = new List<PasswordObject> ();

                passwordCryptList = ObjectSerializer.DeserializeObject<List<PasswordCryptObject>> (fileName);

                foreach (PasswordCryptObject passwordObject in passwordCryptList) {
                    passwordList.Add (EncryptPasswordObject.Decrypt (passwordObject, password));
                }

                if (PasswordItem.GetPasswordStringFromPasswordObject (passwordList[0]).Equals (password)) {
                    passwordList.Remove (passwordList[0]);

                    PasswordObjectComparer comparer = new PasswordObjectComparer ();
                    // Set comparaison method to DisplayName
                    comparer.ComparisonMethod = PasswordObjectComparer.ComparisonType.Id;

                    passwordList.Sort (comparer);

                    return passwordList;
                }
                else {
                    return null;
                }
            }
            catch {
                return null;
            }
        }

        private void SavePasswordListToXMLFile (List<PasswordObject>passwordList,  string filename, string password) {
            List<PasswordObject> readPasswordList = new List<PasswordObject> ();

            readPasswordList.Add (PasswordItem.GetPasswordObjectFromPassword (password));

            if (passwordList.Count > 0) {
                readPasswordList.AddRange (passwordList);
            }

            List<PasswordCryptObject> passwordCryptList = new List<PasswordCryptObject> ();

            foreach (PasswordObject passwordObject in readPasswordList) {
                passwordCryptList.Add (EncryptPasswordObject.Encrypt (passwordObject, password));

            }
            ObjectSerializer.SerializeObject<List<PasswordCryptObject>> (filename, passwordCryptList);
        }

        public new  DialogResult ShowDialog () {
            CompareFiles ();

            return base.ShowDialog ();
        }

        private void okBtn_Click (object sender, EventArgs e) {
            SynchronizeFiles ();
        }

    }
}
